#include <string.h>

#include "bsp/bsp_rf_driver.h"
#include "jxos_public.h"
#include <srtnet_config.h>
#include "communication_layer_frame.h"
#include "transmitter.h"
#include "receiver.h"
#include "repeater.h"


#if (SRTNET_COMM_DEVICE_TYPE == SRTNET_COMM_DEVICE_TYPE_RECEIVER)\
    ||(SRTNET_COMM_DEVICE_TYPE == SRTNET_COMM_DEVICE_TYPE_REPEATER)

#if (SRTNET_COMM_DEVICE_TYPE_RECEIVER_IDLE_MODE_ENBALE == 1)
#define receiver_wait_rec_sart_time     5	//2*sync time, make shure the receiver can catch the sync head
#define receiver_receiving_time     	85	//1.5*transmit tmer of the longest frame
#define receiver_idle_time      		2	//2*sync time or == receiver_receiving_time

#define receiver_power_state_wait_rec_sart      0
#define receiver_power_state_receiving     		1
#define receiver_power_state_idle      			2

static uint8_t receiver_power_state = 0;
static swtime_type receiver_power_ctrl_swt;
static JXOS_EVENT_HANDLE event_rf_receiver_start;

uint8_t srtnet_comm_layer_receiver_device_enable_flag = 0;

void (*srtnet_comm_layer_receiver_device_enable_callback)(void) = 0;
void (*srtnet_comm_layer_receiver_device_disable_callback)(void) = 0;
#endif

static JXOS_EVENT_HANDLE event_rf_receiver_ok;

uint8_t srtnet_comm_layer_receiver_device_receiver_ok_falg = 0;
uint8_t srtnet_comm_layer_receiver_device_receiver_buffer[FRAME_PAYLOAD_MAX_LEN+5] = {0};
uint8_t srtnet_comm_layer_receiver_device_receiver_frame_len = 0;

void (*srtnet_comm_layer_receiver_device_indication_data_receive)(SRTNET_COMM_REC_DATA_STRUCT* receive_data) = 0;

static void srtnet_comm_rf_receiver_ok_callback_handler(void)
{
    jxos_event_set(event_rf_receiver_ok);
}
#if (SRTNET_COMM_DEVICE_TYPE_RECEIVER_IDLE_MODE_ENBALE == 1)
static void srtnet_comm_rf_receiver_start_callback_handler(void)
{
    jxos_event_set(event_rf_receiver_start);
}
static void goto_receiver_power_state_idle(void)
{
	sys_software_timer_task_set_timer(receiver_power_ctrl_swt, receiver_idle_time);
	sys_software_timer_task_restart_timer(receiver_power_ctrl_swt);
	receiver_power_state = receiver_power_state_idle;
	srtnet_comm_layer_receiver_device_enable_flag = 0;
	if(srtnet_comm_layer_receiver_device_disable_callback != 0){
		srtnet_comm_layer_receiver_device_disable_callback();
	}
}
static void goto_receiver_power_state_wait_rec_sart(void)
{
	sys_software_timer_task_set_timer(receiver_power_ctrl_swt, receiver_wait_rec_sart_time);
	sys_software_timer_task_restart_timer(receiver_power_ctrl_swt);
	receiver_power_state = receiver_power_state_wait_rec_sart;
	srtnet_comm_layer_receiver_device_enable_flag = 1;
	if(srtnet_comm_layer_receiver_device_enable_callback != 0){
		srtnet_comm_layer_receiver_device_enable_callback();
	}
}
static void goto_receiver_power_state_receiving(void)
{
	sys_software_timer_task_set_timer(receiver_power_ctrl_swt, receiver_receiving_time);
	sys_software_timer_task_restart_timer(receiver_power_ctrl_swt);
	receiver_power_state = receiver_power_state_receiving;
	srtnet_comm_layer_receiver_device_enable_flag = 1;
	if(srtnet_comm_layer_receiver_device_enable_callback != 0){
		srtnet_comm_layer_receiver_device_enable_callback();
	}
}

void srtnet_comm_layer_receiver_device_keep_enable(uint8_t keep_enable)
{
	if(keep_enable == 1){
		goto_receiver_power_state_receiving();
		sys_software_timer_task_stop_timer(receiver_power_ctrl_swt);
	}
	else{
		goto_receiver_power_state_idle();
	}
}
#endif

void srtnet_comm_layer_receiver_device_init(void)
{
#if (SRTNET_COMM_DEVICE_TYPE_RECEIVER_IDLE_MODE_ENBALE == 1)
    receiver_power_ctrl_swt = sys_software_timer_task_new_timer();
	goto_receiver_power_state_wait_rec_sart();
    event_rf_receiver_start = jxos_event_create();
    bsp_rf_receive_ing_call_back = srtnet_comm_rf_receiver_start_callback_handler;
#endif
	
    event_rf_receiver_ok = jxos_event_create();

    srtnet_comm_layer_receiver_device_receiver_ok_falg = 0;
    memset(srtnet_comm_layer_receiver_device_receiver_buffer, 0, FRAME_PAYLOAD_MAX_LEN+5);
    srtnet_comm_layer_receiver_device_receiver_frame_len = 0;
    srtnet_comm_layer_receiver_device_indication_data_receive = 0;

    bsp_rf_receive_init();
    bsp_rf_receive_ok_call_back = srtnet_comm_rf_receiver_ok_callback_handler;
}

/**********************************************************************************
receiver_power_state_wait_rec_sart   ---receiver_power_ctrl_swt--->   receiver_power_state_idle
receiver_power_state_receiving       ---receiver_power_ctrl_swt--->   receiver_power_state_idle
receiver_power_state_idle			 ---receiver_power_ctrl_swt--->   receiver_power_state_wait_rec_sart
all state                            ---event_rf_receiver_ok   --->   receiver_power_state_wait_rec_sart
not receiver_power_state_receiving   ---event_rf_receiver_start--->   receiver_power_state_receiving
**********************************************************************************/
void srtnet_comm_layer_receiver_device_handler(void)
{
	SRTNET_COMM_REC_DATA_STRUCT st;
    uint8_t get_repeat_frame = 0;
    uint8_t buff[FRAME_PAYLOAD_MAX_LEN];
	st.source_node_addr = 0;
	st.receive_playload = buff;
	
    if(jxos_event_wait(event_rf_receiver_ok) == 1){
/**********************************************************************************/
//rec data handler
        if(bsp_rf_receive_buff_len == srtnet_comm_layer_receiver_device_receiver_frame_len){
            if(memcmp(bsp_rf_receive_buff, srtnet_comm_layer_receiver_device_receiver_buffer, bsp_rf_receive_buff_len) == 0){
                get_repeat_frame = 1;
				bsp_rf_receive_finish_receive_falg = 0;		//unlock the bsp rf receiver when the bsp rec data are copied already
            }
        }

        if(get_repeat_frame == 0){
            memcpy(srtnet_comm_layer_receiver_device_receiver_buffer, bsp_rf_receive_buff, bsp_rf_receive_buff_len);
			bsp_rf_receive_finish_receive_falg = 0;			//unlock the bsp rf receiver when the bsp rec data are copied already
            srtnet_comm_layer_receiver_device_receiver_frame_len = bsp_rf_receive_buff_len;
            srtnet_comm_layer_receiver_device_receiver_ok_falg = 1;
#if (SRTNET_COMM_LAYER_DEBUG_PRINT_ENABLE == 1)
			sys_debug_print_task_user_print_str("srtcomm rfrec: ");
			sys_debug_print_task_user_print_data_stream_in_hex(srtnet_comm_layer_receiver_device_receiver_buffer, srtnet_comm_layer_receiver_device_receiver_frame_len);
			sys_debug_print_task_user_print_str("\r\n");
#endif
            if(deframe(srtnet_comm_layer_receiver_device_receiver_buffer, srtnet_comm_layer_receiver_device_receiver_frame_len, buff, &(st.receive_playload_len), &(st.source_node_addr)) == 1){

                //communication layer rec cmd
                if((srtnet_comm_layer_receiver_device_receiver_buffer[0] == FRAME_HEAD_BROADCAST)
                &&(st.source_node_addr == ADDR_BROADCAST)){
                    switch(buff[0]){
                    default:
                        break;
                    }
                }
				//communication layer rec data
				else{
					if(srtnet_comm_layer_receiver_device_indication_data_receive != 0){
						srtnet_comm_layer_receiver_device_indication_data_receive(&st);
					}
				}
            }
        }
/**********************************************************************************/
#if (SRTNET_COMM_DEVICE_TYPE_RECEIVER_IDLE_MODE_ENBALE == 1)
		if(sys_software_timer_task_check_running_timer(receiver_power_ctrl_swt) == 1){
			goto_receiver_power_state_wait_rec_sart();
		}
#endif
    }

#if (SRTNET_COMM_DEVICE_TYPE_RECEIVER_IDLE_MODE_ENBALE == 1)
	if(jxos_event_wait(event_rf_receiver_start) == 1){
		if((receiver_power_state != receiver_power_state_receiving)
		&&(sys_software_timer_task_check_running_timer(receiver_power_ctrl_swt) == 1)){
			goto_receiver_power_state_receiving();
		}
	}

    if(sys_software_timer_task_check_overtime_timer(receiver_power_ctrl_swt) == 1){
		switch (receiver_power_state){
		case receiver_power_state_idle:
			bsp_rf_receive_init();
			goto_receiver_power_state_wait_rec_sart();
			break;

		case receiver_power_state_wait_rec_sart:
		case receiver_power_state_receiving:
		default:
			goto_receiver_power_state_idle();
			break;
		}
    }
#endif	
}

#endif
